import java.util.Scanner;
import java.util.ArrayList;

/**
 * @brief Sample Java program using Eclipse, Git, Google Code and Doxygen written for  CMPE 352 by Group 3
 * @author Eralp Bayraktar, Cafer Caferov, Fazilet Cilli, Huseyin Demirtas, Rasit Mete Esrefoglu, Utku Mert, Setenay Ronael, Ozan Yalcin for cmpesweng2013group3
 * @date May 2013
 */
public class javaProject {
	/**
	 * @param args
	 */
	public static Scanner sc= new Scanner(System.in);
		
	
	/**
	 * This method outputs the first n Fibonacci numbers.
	 * @param n
	 * @return arrlist
	 */
	public static ArrayList<Integer> fibonacci(int n) {
		ArrayList<Integer> arrlist = new ArrayList<Integer>(); 
		int fib1 = 0;
		arrlist.add(fib1);
		int fib2 = 1;
		arrlist.add(fib2);
		for(int i=2; i<n;i++) {
			int temp = fib2;
			fib2 = fib1 + fib2;
			arrlist.add(fib2);
			fib1 = temp;
		}
		return arrlist;
	}
	
	
	/**
	 * This method returns the factorial of the given number.
	 * @param n
	 * @return
	 */
	public static int factorial(int n)
	{
		if(n == 0)
			return 1;
		else
			return n*factorial(n-1);
	}
	
	
	/**
	 * This method returns the sum of squares of the numbers from 1 to given number.
	 * @param n
	 * @return
	 */
	public static int sqrtsum(int n)
	{
		int sum=0;
		for(int i=0;i<=n;i++)
		{
			sum += i*i;
		}
		return sum;
	}
	
	/**
	 * This method outputs the sum of the numbers to power of "-1" from 1 to given number.
	 * @param n
	 * @return
	 */
	public static double negexpsum (int n) {
		double result=1.0;

		for (int i=2; i<=n; i++) {
			result=result+1.0/i;
		}

		return result;
	}
	
	/**
	 * This method outputs the sum of cubes of the numbers from 1 to given number.
	 * @param n
	 * @return
	 */
	public static int cubes(int n)
	{
		int sum=0;
		for(int i=0;i<=n;i++)
		{
			sum += i*i*i;
		}
		return sum;
	}
	
		/**
		 * This method returns the sum of products of equally far from the center of the series beginning from 1 to given number (e.g. for a given number 20, it returns 1x20 + 2x19 + 3x18 +..... + 10x11).
		 * @param n
		 * @return
		 */
    	public static int sumOfEquallyFarProducts (int n)
        {
		int sum = 0;
		int endpoint = n;
		int startpoint = 1;
                while (startpoint < endpoint) {
			sum = sum + startpoint*endpoint;
			startpoint = startpoint + 1;
			endpoint = endpoint - 1;
		}                 
		return sum;
		
		// sample comment
		
        }
    	
    	/**
    	 * This method outputs the numbers that can be divided to "3" in the series from 0 to given number.
    	 * @param n
    	 * @return
    	 */
	public static ArrayList<Integer> multiplesOfThree(int n) {
		ArrayList<Integer> arrlist = new ArrayList<Integer>();
		for (int i=0; i<=n; i+=3) {
			arrlist.add(i);
		}
		return arrlist;
	}
	
	
	/**
	 * This method outputs the geometric Mean of the series from 1 to given number.
	 * @param n
	 * @return
	 */
	// this method returns the geometric mean of integers up to the number n which is given by the user
	public static double geometricMean(int n)
	{
		int product = 1;
		for(int i=1; i<=n; i++) { product *=i; }
		return Math.pow(product, 1.0/n);
	}
	
	
	/**
	 * This method returns the prime numbers in the series from 1 to given number.
	 * @param number
	 * @return
	 */
	public static ArrayList<Integer> primes(int number) {
		ArrayList<Boolean> isMarked = new ArrayList<Boolean>();
		ArrayList<Integer> primeList = new ArrayList<Integer>();
		
		if(number <= 1)
			return primeList;
		
		for(int i = 0; i<=number+1; i++)
			isMarked.add(false);

		isMarked.set(0,true);
		isMarked.set(1,true);
		
		int currentPrime = 2;
		while(currentPrime <= number)
		{
			isMarked.set(currentPrime,true);
			primeList.add(currentPrime);
			int multiple = 2;
			while(multiple*currentPrime <= number)
			{
				isMarked.set(currentPrime*multiple,true);
				multiple++;
			}
			
			//Find the next un-marked entry
			for(int i = currentPrime;i<=number;i++)
			{
				if(isMarked.get(i) == false)
				{
					currentPrime = i;
					break;
				}
			}
			
			//Check if we could find one
			if(isMarked.set(currentPrime,true))
				break;
		}
			
		return primeList;
	}

	/**
	 * This is the starting point where user enters an integer to select a method of his/her choosing.
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int choice=0;
		int n;
		while(true){
			System.out.println("\nPlease choice one of the following operations");
			System.out.println("Enter 1 to get first n fibonacci numbers");
			System.out.println("Enter 2 to calculate n factorial");
			System.out.println("Enter 3 to sum of square roots of 1..n ");
			System.out.println("Enter 4 to sum of negative exponential(-1) of 1..n ");
			System.out.println("Enter 5 to sum of cubes of 1..n ");
			System.out.println("Enter 6 to sum of products of the numbers that are equally far from the mid-point of n ");
			System.out.println("Enter 7 to get numbers that can be perfectly divided into 3 from 1..n");
			System.out.println("Enter 8 to find geometric mean of 1..n");
			System.out.println("Enter 9 to find primes up to n");
			System.out.println("Enter 0 to Exit");
			choice = sc.nextInt();
			switch(choice)
			{
			case 1:
				System.out.println("Please enter n");
				n = sc.nextInt();
				ArrayList<Integer> arrlist = fibonacci(n);
				System.out.println("First " + n + " fibonacci numbers are:");
				for(int i=0; i<n ; i++) {
					System.out.print(arrlist.get(i) + " ");
				}
				System.out.println();
				break;
			case 2:
				System.out.println("Please enter n");
				n = sc.nextInt();
				int res = factorial(n);
				System.out.println("Factorial of " + n + " is: " + res);
				break;
			case 3: 
				System.out.println("Please enter n");
				n = sc.nextInt();
				n = sqrtsum(n);
				System.out.println("Square root sum is " + n);
				break;

			case 4: 
				System.out.println("Please enter n");
				n = sc.nextInt();
				double m = negexpsum(n);
				System.out.println("Negative exponents' sum is " + m);
				break;
			case 5: 
				System.out.println("Please enter n");
				n = sc.nextInt();
				n = cubes(n);
				System.out.println("Cubes sum is " + n);
				break;
			case 6:
				System.out.println("Please enter n");
				n = sc.nextInt();
				m = sumOfEquallyFarProducts (n);
				System.out.println("Sum of products of the numbers that are equally far from the mid-point of " + n + " is " + m);
				break;
			case 7:
				System.out.println("Please enter n");
				n = sc.nextInt();
				ArrayList<Integer> arr = multiplesOfThree(n);
				System.out.println("The numbers that can be perfectly divided into 3 are: ");
				for(int i=0; i<arr.size() ; i++) {
					System.out.print(arr.get(i) + " ");
				}
				System.out.println("");
				break;
			case 8:
				System.out.println("Please enter n");
				n = sc.nextInt();
				double mean = geometricMean(n);
				System.out.println("Geometric mean of 1.." + n + " is: " + mean);
				break;
			case 9:
				System.out.println("Please enter n");
				n = sc.nextInt();
				ArrayList<Integer> result = primes(n);
				
				System.out.println("Primes are: ");
				for(int i=0; i<result.size() ; i++) {
					System.out.print(result.get(i) + " ");
				}
				System.out.println("");
				break;
			case 0:
				break;
			default:
				break;
			}
			if(choice == 0) break;
		}
	}
}

